# user.py
import codecs

from flask import Blueprint, jsonify, request,session
from models import User, db, PatientTable
from werkzeug.security import check_password_hash, generate_password_hash
import jwt
import csv
from io import TextIOWrapper
from chardet.universaldetector import UniversalDetector
user_api = Blueprint('user_api', __name__)

# 获取用户列表
@user_api.route('/getUserList', methods=['GET'])
def get_authors():
    user_total = User.query.count()
    user_list = User.query.all()
    result_list = [{'account': user.account, 'id': user.id} for user in user_list]
    data = {'code': 200, 'data': result_list, 'total': user_total}
    return jsonify(data)

# 添加用户
@user_api.route('/addUser', methods=['POST'])
def add_user():
    data = request.get_json()
    print(data)
    account = data.get('account')
    password = data.get('password')
    email = data.get('email')
    role = data.get('role')
    if account and password:
        try:
            new_user = User.create_user(account, password,email,role)

            db.session.add(new_user)
            db.session.commit()
            return jsonify({'code': 200, 'data': {'id': new_user.id, 'account': new_user.account}})
        except Exception as e:
            return jsonify({'code': 500, 'data': str(e)})
    else:
        return jsonify({'code': 400, 'data': '请输入账号密码'})
    
@user_api.route('/updateUserInfo', methods=['POST'])
def update_user_info():
    # 获取JWT token
    token = request.headers.get('Authorization')
    if not token:
        return jsonify({'code': 401, 'data': '未提供认证令牌'}), 401
    try:
        # 验证token
        payload = jwt.decode(token, 'secret', algorithms=['HS256'])
        user_id = payload['user_id']
    except jwt.ExpiredSignatureError:
        return jsonify({'code': 401, 'data': '令牌过期'}), 401
    except jwt.InvalidTokenError:
        return jsonify({'code': 401, 'data': '无效的令牌'}), 401

    # 获取请求中的数据
    data = request.get_json()
    new_account = data.get('account')
    new_password = data.get('password')
    new_email = data.get('email')
    new_role = data.get('role')
    new_sex=data.get('sex')
    # 查询用户
    user = User.query.get(user_id)
    if not user:
        return jsonify({'code': 404, 'data': '用户不存在'}), 404

    # 更新用户信息
    try:
        if new_account:
            user.account = new_account
        if new_password:
            user.password_hash = generate_password_hash(new_password)
        if new_email:
            user.email = new_email
        if new_role:
            user.role = new_role
        if new_sex:
            user.sex = new_sex
        db.session.commit()
        return jsonify({'code': 200, 'data': '用户信息更新成功'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 500, 'data': str(e)}), 500
@user_api.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        account = request.form.get('account')
        password = request.form.get('password')
        if not account or not password:
            return jsonify({'code': 400, 'data': '请输入账号密码'}), 400
        user = User.query.filter_by(account=account).first()
        
        if user and check_password_hash(user.password_hash, password):
            token = jwt.encode({'user_id': user.id}, 'secret', algorithm='HS256')
            # 密码正确，创建用户会话或生成认证令牌
            session['user_id'] = user.id
            # 这里可以返回用户信息或认证令牌
            if isinstance(token, bytes):
                return jsonify(
                    {'code': 200, 'data': {'id': user.id,'role':user.role,
                                           'account': user.account,
                                           'email':user.email,
                                           'sex':user.sex,
                                           'token': token.decode('utf-8')}})
            else:
                return jsonify({'code': 200, 'data': {'id': user.id, 'role':user.role,
                                                      'account': user.account,
                                                      'email': user.email,
                                                      'sex': user.sex,
                                                      'token': token}})
        else:
            # 用户不存在或密码错误
            return jsonify({'code': 400, 'data': '密码或账号错误'})

    # 如果不是POST请求，返回一个提示或重定向
    return jsonify({'code': 405, 'data': '方法不被允许'}), 405


# 上传CSV文件并写入数据库
@user_api.route('/uploadCSV', methods=['POST'])
def upload_csv():
    # 检查是否有文件在请求中
    if 'file' not in request.files:
        return jsonify({'code': 400, 'data': '没有文件部分'}), 400
    file = request.files['file']

    # 如果用户没有选择文件，浏览器可能会发送一个没有文件名的空部分
    if file.filename == '':
        return jsonify({'code': 400, 'data': '没有选择文件'}), 400

    if file and allowed_file(file.filename):
        # 处理CSV文件
        try:
            process_csv_file(file)
            return jsonify({'code': 200, 'data': 'CSV文件已成功上传并写入数据库'}), 200
        except Exception as e:
            return jsonify({'code': 500, 'data': str(e)}), 500
    else:
        return jsonify({'code': 400, 'data': '不允许的文件类型'}), 400


def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() == 'csv'


def process_csv_file(file):
    # 尝试自动检测文件编码
    detector = UniversalDetector()
    for line in file.stream:
        detector.feed(line)
        if detector.done:
            break
    detector.close()
    file_encoding = detector.result['encoding']

    # 如果检测到编码，尝试使用该编码读取文件
    if file_encoding:
        try:
            file.stream.seek(0)
            text_stream = TextIOWrapper(file.stream, encoding=file_encoding, errors='replace')
            csv_reader = csv.DictReader(text_stream)

            records = []
            for row in csv_reader:
                 records.append(row)
                # 这里可以添加将数据写入数据库的代码
                 patientTables= PatientTable.create_from_csv_row(row)
                 print(patientTables)
            # 假设的数据库提交操作
            db.session.commit()
            return {'code': 200, 'data': '文件上传并处理成功'}
        except UnicodeDecodeError:
            return {'code': 500, 'data': '解码错误，请检查文件编码'}
        except Exception as e:
            # 其他异常，回滚数据库会话
            db.session.rollback()
            return {'code': 500, 'data': str(e)}
    else:
        return {'code': 500, 'data': '无法检测到文件编码，请检查文件是否为支持的格式'}


# 获取管理员列表
@user_api.route('/get_admin_list', methods=['GET'])
def get_patient_list():
    users = User.query.all()

    users_list = [
        {
            'id': user.id,
            'account': user.account,

        }
        for user in users
    ]

    data = {
        'code': 200,
        'data': users_list
    }

    # 返回结果
    return jsonify(data)